home *** CD-ROM | disk | FTP | other *** search
Text File | 1997-07-20 | 6.7 KB | 296 lines | [TEXT/CWIE] |
- //Copyright (c) 1997 Aidan Cully
- //All rights reserved
-
- #include "CLWindowLayer.h"
- #include "CLBaseWindow.h"
- #include "CLApplication.h"
- #include "CLMouseHandler.h"
-
- TWindowLayer *TWindowLayer::sFrontLayer= 0;
- TWindowLayer *gFloatingWindowLayer, *gNormalWindowLayer;
-
- TWindowLayer::TWindowLayer():
- mBelow( 0 ),
- mAbove( 0 ),
- mActive( true )
- {
- if( !sFrontLayer )
- sFrontLayer= this;
- mBelow= 0;
- mAbove= 0;
- }
-
- TWindowLayer::~TWindowLayer()
- {
- if( mAbove )
- mAbove->mBelow= mBelow;
- mBelow->mAbove= mAbove;
- }
-
- TBaseWindow *TWindowLayer::FindLastWindowAbove()
- {
- if( !mAbove )
- return( 0 );
- TWindowLayer *iter= mAbove;
- bool found= false;
- while( !found&&iter ) {
- found= iter->mhWindows.MoveLast();
- if( !found )
- iter= iter->mAbove;
- }
- if( !found )
- return( 0 );
- TBaseWindow *ret;
- iter->mhWindows.GetData( ret );
- return( ret );
- }
-
- void TWindowLayer::AddWindow( TBaseWindow *win )
- {
- if( IsActive()&&(!mhWindows.MoveFirst()) ) {
- mhWindows.AddPrev( win );
- TBaseWindow *above= FindLastWindowAbove();
- WindowRef macWin= win->GetWindow();
- if( above ) {
- ::SendBehind( macWin, above->GetWindow() );
- ::ShowWindow( macWin );
- } else {
- ::ShowWindow( macWin );
- ::BringToFront( macWin );
- }
- if( IsActive() )
- win->MakeActive( true );
- TApplication::SCurApp()->AddBackgrounder( this );
- } else {
- if( mhWindows.FindIndex( win )!=-1 )
- return;
- mhWindows.MoveFirst();
- if( IsActive() ) {
- TBaseWindow *oWin;
- mhWindows.GetData( oWin );
- oWin->MakeActive( false );
- }
- TBaseWindow *above= FindLastWindowAbove();
- if( above ) {
- ::SendBehind( win->GetWindow(), above->GetWindow() );
- ::ShowWindow( win->GetWindow() );
- } else {
- ::ShowWindow( win->GetWindow() );
- ::BringToFront( win->GetWindow() );
- }
- mhWindows.AddPrev( win );
- if( IsActive() )
- win->MakeActive( true );
- }
- TMouseHandler::SGetMouse()->CalcMouseMoveRgn();
- }
-
- void TWindowLayer::RemoveWindow( TBaseWindow *win )
- {
- if( !mhWindows.GoToElem( mhWindows.FindIndex( win ) ) )
- return;
- if( !mhWindows.MovePrev() ) {
- ::HideWindow( win->GetWindow() );
- mhWindows.Remove();
- if( mhWindows.MoveFirst() ) {
- if( IsActive() ) {
- mhWindows.GetData( win );
- win->MakeActive( true );
- }
- } else
- TApplication::SCurApp()->RemoveBackgrounder( this );
- } else {
- mhWindows.MoveNext();
- mhWindows.Remove();
- }
- TMouseHandler::SGetMouse()->CalcMouseMoveRgn();
- }
-
- TBaseWindow *TWindowLayer::FindWindow( Point pt )
- {
- if( !mhWindows.MoveFirst() ) {
- if( mBelow )
- return( mBelow->FindWindow( pt ) );
- return( 0 );
- }
- TBaseWindow *win;
- bool found= false;
- RgnHandle winRgn= ::NewRgn();
- do {
- mhWindows.GetData( win );
- ::GetWindowStructureRgn( win->GetWindow(), winRgn );
- if( ::PtInRgn( pt, winRgn ) )
- found= true;
- } while( !found&&mhWindows.MoveNext() );
- ::DisposeRgn( winRgn );
- if( found )
- return( win );
- if( mBelow )
- return( mBelow->FindWindow( pt ) );
- return( 0 );
- }
-
- void TWindowLayer::CalcMouseMove( Point pt, RgnHandle rgn )
- {
- if( !::FrontWindow() )
- return;
- TBaseWindow *frontWin= ((TBaseWindow*)::GetWRefCon( ::FrontWindow() ));
- RgnHandle above= ::NewRgn();
- frontWin->ClipAbove( above );
- Rect bigRect;
- ::SetRect( &bigRect, -32767, -32767, 32767, 32767 );
- if( !::PtInRgn( pt, above ) ) {
- ::RectRgn( rgn, &bigRect );
- ::DiffRgn( rgn, above, rgn );
- ::DisposeRgn( above );
- return;
- }
- ::CopyRgn( above, rgn );
- if( CalcMouseMoveBelow( pt, rgn ) ) {
- ::DisposeRgn( above );
- return;
- }
- TWindowLayer *iter= this;
- while( iter ) {
- if( iter->IsActive()&&iter->mhWindows.MoveFirst() ) {
- WindowRef win;
- Point ul;
- do {
- iter->mhWindows.GetData( frontWin );
- win= frontWin->GetWindow();
- ::SetPort( win );
- ul.h= 0; ul.v= 0;
- ::GetWindowStructureRgn( win, above );
- ::DiffRgn( rgn, above, rgn );
- } while( iter->mhWindows.MoveNext() );
- }
- iter= iter->mBelow;
- }
- ::DisposeRgn( above );
- }
-
- bool TWindowLayer::CalcMouseMoveBelow( Point pt, RgnHandle rgn )
- {
- if( !mhWindows.MoveFirst() )
- if( mBelow )
- return( mBelow->CalcMouseMoveBelow( pt, rgn ) );
- else
- return( false );
- TBaseWindow *win;
- bool found= false;
- RgnHandle rect= ::NewRgn();
- RgnHandle winRgn= ::NewRgn();
- Point ul, temp;
- ul.h= 0;
- ul.v= 0;
- do {
- mhWindows.GetData( win );
- temp= ul;
- ::SetPort( win->GetWindow() );
- ::LocalToGlobal( &temp );
- ::GetWindowStructureRgn( win->GetWindow(), winRgn );
- if( ::PtInRgn( pt, winRgn ) )
- found= true;
- else {
- ::GetWindowStructureRgn( win->GetWindow(), rect );
- ::DiffRgn( rgn, rect, rgn );
- }
- } while( !found&&mhWindows.MoveNext() );
- if( !found ) {
- ::DisposeRgn( rect );
- if( mBelow )
- return( mBelow->CalcMouseMoveBelow( pt, rgn ) );
- else
- return( false );
- }
- ::GetWindowStructureRgn( win->GetWindow(), rgn );
- win->ClipAbove( rect );
- ::SectRgn( rect, rgn, rect );
- win->CalcMouseMove( pt, rgn );
- ::SectRgn( rgn, rect, rgn );
- ::DisposeRgn( rect );
- return( true );
- }
-
- void TWindowLayer::AddLayer( TWindowLayer *layer )
- {
- if( mBelow )
- mBelow->mAbove= layer;
- layer->mBelow= mBelow;
- layer->mAbove= this;
- mBelow= layer;
- }
-
- TBaseWindow *TWindowLayer::FrontWindow()
- {
- if( !mhWindows.MoveFirst() )
- return( 0 );
- TBaseWindow *win;
- mhWindows.GetData( win );
- return( win );
- }
-
- void TWindowLayer::SelectWindow( TBaseWindow *win )
- {
- TBaseWindow *awin;
- if( mhWindows.MoveFirst() ) {
- mhWindows.GetData( awin );
- if( awin==win )
- return;
- }
- if( !mhWindows.GoToElem( mhWindows.FindIndex( win ) ) )
- return;
- awin->MakeActive( false );
- mhWindows.Remove();
- mhWindows.MoveFirst();
- mhWindows.AddPrev( win );
- if( mAbove&&mAbove->mhWindows.MoveLast() ) {
- TBaseWindow *awin;
- mAbove->mhWindows.GetData( awin );
- ::SendBehind( win->GetWindow(), awin->GetWindow() );
- if( IsActive() )
- win->MakeActive( true );
- } else {
- ::BringToFront( win->GetWindow() );
- if( IsActive() )
- win->MakeActive( true );
- }
- TMouseHandler::SGetMouse()->CalcMouseMoveRgn();
- }
-
- void TWindowLayer::SendBehind( TBaseWindow *selector, TBaseWindow *front )
- {
- SINT16 indexS= mhWindows.FindIndex( selector );
- SINT16 indexF= mhWindows.FindIndex( front );
- if( (indexS==-1)||(indexF==-1) )
- return;
- mhWindows.GoToElem( indexS );
- mhWindows.Remove();
- mhWindows.GoToElem( indexF );
- mhWindows.AddPrev( selector );
- ::SendBehind( selector->GetWindow(), front->GetWindow() );
- }
-
- void TWindowLayer::MakeActive( bool active )
- {
- if( mActive!=active ) {
- mActive= active;
- if( mhWindows.MoveFirst() ) {
- TBaseWindow *win;
- mhWindows.GetData( win );
- win->MakeActive( mActive );
- }
- if( active )
- TMouseHandler::SGetMouse()->CalcMouseMoveRgn();
- }
- }
-
- void TWindowLayer::HandleBackground( const TBackgroundEvent *ev )
- {
- MakeActive( !ev->background );
- //if( mhWindows.MoveFirst() ) {
- // TBaseWindow *win;
- // mhWindows.GetData( win );
- // win->MakeActive( !ev->background );
- //}
- }